iT邦幫忙

0

Weydub 字幕擦除工作流:把 OCR 結果轉成有範圍、有時間的處理決策

  • 分享至 

  • xImage
  •  

我是 Weydub 團隊的成員,這篇分享我們公開文件中的字幕擦除工作流,以及一個在本機驗證的區域參數示例。文章有 AI 協助整理;參數與結果經核對。它不是模型效果評測,也不公開未披露的內部模型架構。

專案資訊與實作入口

Weydub 是已上線的影片本地化工具,處理燒錄字幕/畫面文字擦除、字幕生成、翻譯與 AI 配音。這裡只談其中一個工程問題:怎樣把「這段字幕要消失,但商品包裝文字要留下」表達成明確的處理資料。

產品入口:Weydub 繁體中文站。實際影片處理需要登入並依方案使用點數;下文的本機參數示例不需要帳號,也不會提交影片任務。

開發動機:辨識到文字,不代表應該擦掉

OCR 會看到字幕,也會看到招牌、型號、衣服字樣和商品包裝。如果只把所有文字框送去修復,錯誤會從辨識階段一路放大到輸出。這也是為什麼擦除工作流需要區分「候選文字」與「允許處理的範圍」。

另一個容易忽略的維度是時間。角落的提示只在第 3 到第 8 秒出現,若整支影片都處理那個位置,後面的臉部或商品可能被不必要地修改。空間框與時間窗應該一起保存。

架構分層:介面資料、公開請求與背景修復

在前端,使用者拖曳的是預覽圖上的框;處理請求需要的是與預覽大小無關的座標。可把工作拆成三層:

  1. 輸入層:記錄區域端點、時間範圍與處理意圖。
  2. 請求層:驗證座標,序列化蒙版,提交非同步任務並保存回傳的任務識別碼。
  3. 輸出層:等待實際完成,再檢查畫面連續性與應保留的文字。

這是工作流責任的分層,不代表某個特定神經網路的結構。公開技術解讀中提到的時序候選圖是說明模型;PaddleOCR、LaMa、ProPainter 等也是研究參考,不能據此推斷它們就是 Weydub 的內部依賴。

核心邏輯:預覽像素轉成正規化四點

假設有效影片預覽為 640×360,選區端點是 (64,270)(576,342)。每個 x 除以 640、每個 y 除以 360,結果為:

[[0.1,0.75],[0.9,0.75],[0.9,0.95],[0.1,0.95]]

順序是左上、右上、右下、左下。同樣的相對區域放到 1920×1080 影片上,就對應 (192,810)(1728,1026)。這只適用於相同比例與內容構圖;影片經過裁切後不能盲目重用。

還有一個介面陷阱:分母必須是實際顯示影片的區域,不是包含黑邊的外層容器。若使用 object-fit: contain,必須先扣除留白與偏移,才可以換算。

下面是獨立的 JavaScript 示意函式,不是從私有程式碼貼出的產品模組。它拒絕不合法區域,而不是默默猜測使用者的意圖:

function makeMask({ width, height, box, start, end, duration }) {
  const values = [width, height, ...box, start, end, duration];
  if (!values.every(Number.isFinite)) throw new Error('Non-finite value');
  const [x0, y0, x1, y1] = box;
  if (width <= 0 || height <= 0 || x0 < 0 || y0 < 0 ||
      x1 > width || y1 > height || x0 >= x1 || y0 >= y1 ||
      start < 0 || end <= start || end > duration) {
    throw new Error('Invalid region or time interval');
  }
  return {
    type: 'remove_only_ocr', start, end,
    region: [[x0 / width, y0 / height], [x1 / width, y0 / height],
      [x1 / width, y1 / height], [x0 / width, y1 / height]],
  };
}
const mask = makeMask({
  width: 640, height: 360, box: [64, 270, 576, 342],
  start: 3, end: 8, duration: 12,
});
const fragment = {
  needChineseOcclude: 2,
  videoInpaintMasks: JSON.stringify([mask]),
};
console.log(fragment);

這只是請求片段,沒有來源 URL、認證或簽名,不能直接當成完整 API 呼叫。依公開文件,videoInpaintMasks 在簽名前應是緊湊的 JSON 字串;不要誤把介面內的陣列直接當成最終格式。

本機以 Node.js 與 node:assert/strict 檢查了四點座標、JSON 序列化往返,以及零寬度、反向框、時間超過片長和非有限數值的拒絕行為,均通過。這些測試只證明參數示例的行為,沒有驗證線上模型效果。

處理意圖與時間的語義

公開文件區分 remove(處理區域)、keep(保留區域)與 remove_only_ocr(處理區域內 OCR 偵測到的文字)。選哪一種取決於內容,而不是一律用最大的遮罩。

12 秒影片只處理第 3 到第 8 秒時,可以用 start: 3, end: 8。有些工具使用 to_end 表示距離片尾的秒數;在這個例子中是 4,不是 8。已知結束時間時,公開 API 建議明確傳 end,減少語義混淆。

成功回應不等於影片已完成,也不等於畫質合格

非同步任務需要先保存專案與工作識別碼,等待完成狀態,再讀輸出網址。接到提交回應後立刻把它標成「完成」,會讓使用者看到尚未可用的結果。

影片修復還需要時間連續性:單張看起來合理的補紋,在播放時可能閃爍。檢查應包含開頭、中段、結尾,以及鏡頭切換、臉和手、規則紋理、商品邊緣等位置。API 與批次是交付方式,不是額外的畫質等級。

擦除、生成、翻譯配音要分開理解

擦除改變既有畫面文字;字幕生成建立文字與時間;翻譯配音處理目標語言與聲音。生成新字幕不會自動消除舊的燒錄字幕,換音軌也不會。把這些狀態分開,才能定位「新舊字幕重疊」究竟是哪個步驟漏掉。

如果你也做過影片區域編輯器,會選擇在輸入時拒絕越界框,還是將它裁切到有效畫面?兩種策略會對使用者預期帶來不同影響,值得交流。

技術來源:字幕擦除原理解讀公開蒙版與時間參數文件


*提醒邦友,使用第三方服務/API 時,請務必評估資安風險與隱私保護
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言